#!/bin/bash

# 生产环境快速部署脚本

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 打印带颜色的消息
print_message() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC}"
}

# 显示帮助信息
show_help() {
    print_message $BLUE "生产环境部署脚本"
    echo ""
    echo "用法: ./deploy.sh [命令]"
    echo ""
    echo "命令:"
    echo "  setup       初始化生产环境"
    echo "  deploy      部署应用"
    echo "  update      更新应用"
    echo "  rollback    回滚到上个版本"
    echo "  status      查看应用状态"
    echo "  logs        查看应用日志"
    echo "  restart     重启应用"
    echo "  stop        停止应用"
    echo "  backup      备份数据库"
    echo "  help        显示此帮助信息"
}

# 检查环境
check_environment() {
    print_message $BLUE "检查部署环境..."
    
    # 检查 Node.js
    if ! command -v node &> /dev/null; then
        print_message $RED "错误: Node.js 未安装"
        exit 1
    fi
    
    # 检查 PM2
    if ! command -v pm2 &> /dev/null; then
        print_message $YELLOW "PM2 未安装，正在安装..."
        npm install -g pm2
    fi
    
    # 检查 .env 文件
    if [ ! -f ".env" ]; then
        print_message $YELLOW "警告: .env 文件不存在"
        if [ -f ".env.example" ]; then
            print_message $BLUE "复制环境配置模板..."
            cp .env.example .env
            print_message $YELLOW "请编辑 .env 文件并修改相关配置（特别是数据库密码和JWT密钥）"
            exit 1
        else
            print_message $RED "错误: 请创建 .env 文件"
            exit 1
        fi
    fi
    
    print_message $GREEN "环境检查完成"
}

# 初始化生产环境
setup_production() {
    print_message $GREEN "初始化生产环境..."
    
    check_environment
    
    # 创建日志目录
    mkdir -p logs
    
    # 安装依赖
    print_message $BLUE "安装生产依赖..."
    npm ci --only=production
    
    # 运行数据库迁移
    print_message $BLUE "运行数据库迁移..."
    npm run migrate:latest
    
    # 运行种子数据（可选）
    print_message $YELLOW "是否运行种子数据? (y/N)"
    read -r response
    if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
        npm run seed:run
    fi
    
    print_message $GREEN "生产环境初始化完成"
}

# 部署应用
deploy_application() {
    print_message $GREEN "部署应用..."
    
    check_environment
    
    # 安装依赖
    print_message $BLUE "安装依赖..."
    npm ci --only=production
    
    # 运行数据库迁移
    print_message $BLUE "运行数据库迁移..."
    npm run migrate:latest
    
    # 启动应用
    print_message $BLUE "启动应用..."
    npm run pm2:start
    
    # 保存 PM2 配置
    pm2 save
    pm2 startup
    
    print_message $GREEN "应用部署完成"
    print_message $YELLOW "应用地址: http://localhost:3000"
}

# 更新应用
update_application() {
    print_message $GREEN "更新应用..."
    
    # 拉取最新代码
    print_message $BLUE "拉取最新代码..."
    git pull origin main
    
    # 安装依赖
    print_message $BLUE "更新依赖..."
    npm ci --only=production
    
    # 运行数据库迁移
    print_message $BLUE "运行数据库迁移..."
    npm run migrate:latest
    
    # 重启应用
    print_message $BLUE "重启应用..."
    npm run pm2:restart
    
    print_message $GREEN "应用更新完成"
}

# 回滚应用
rollback_application() {
    print_message $YELLOW "回滚应用..."
    
    # 获取上一个提交
    local last_commit=$(git log --oneline -2 | tail -1 | cut -d' ' -f1)
    
    print_message $BLUE "回滚到提交: $last_commit"
    git reset --hard $last_commit
    
    # 安装依赖
    npm ci --only=production
    
    # 重启应用
    npm run pm2:restart
    
    print_message $GREEN "应用回滚完成"
}

# 查看应用状态
show_status() {
    print_message $BLUE "应用状态:"
    pm2 status
    
    print_message $BLUE "系统资源:"
    pm2 monit --no-interaction || echo "使用 'pm2 monit' 查看详细监控"
}

# 查看应用日志
show_logs() {
    print_message $BLUE "查看应用日志..."
    npm run pm2:logs
}

# 重启应用
restart_application() {
    print_message $BLUE "重启应用..."
    npm run pm2:restart
    print_message $GREEN "应用重启完成"
}

# 停止应用
stop_application() {
    print_message $YELLOW "停止应用..."
    npm run pm2:stop
    print_message $GREEN "应用已停止"
}

# 备份数据库
backup_database() {
    print_message $GREEN "备份数据库..."
    
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local backup_file="backup_${timestamp}.sql"
    
    # 从环境变量读取数据库配置
    source .env
    
    mysqldump -h $DB_HOST -P $DB_PORT -u $DB_USER -p$DB_PASSWORD $DB_NAME > $backup_file
    
    print_message $GREEN "数据库备份完成: $backup_file"
}

# 主程序
main() {
    case "$1" in
        "setup")
            setup_production
            ;;
        "deploy")
            deploy_application
            ;;
        "update")
            update_application
            ;;
        "rollback")
            rollback_application
            ;;
        "status")
            show_status
            ;;
        "logs")
            show_logs
            ;;
        "restart")
            restart_application
            ;;
        "stop")
            stop_application
            ;;
        "backup")
            backup_database
            ;;
        "help"|"")
            show_help
            ;;
        *)
            print_message $RED "错误: 未知命令 '$1'"
            show_help
            exit 1
            ;;
    esac
}

main "$@"